package com.hongtech.tiny.modules.sys.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hongtech.tiny.common.response.ObjectResult;
import com.hongtech.tiny.common.response.PageResult;
import com.hongtech.tiny.common.response.ResultCode;
import com.hongtech.tiny.modules.sys.dto.SysAdminLoginParam;
import com.hongtech.tiny.modules.sys.dto.SysAdminParam;
import com.hongtech.tiny.modules.sys.dto.SysMenuNode;
import com.hongtech.tiny.modules.sys.dto.UpdatePasswordParam;
import com.hongtech.tiny.modules.sys.entity.SysAdmin;
import com.hongtech.tiny.modules.sys.entity.SysRole;
import com.hongtech.tiny.modules.sys.service.SysAdminService;
import com.hongtech.tiny.modules.sys.service.SysCaptchaService;
import com.hongtech.tiny.modules.sys.service.SysMenuService;
import com.hongtech.tiny.modules.sys.service.SysRoleService;
import com.hongtech.tiny.modules.sys.vo.vo.RouterVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 后台用户管理
 */
@RestController
@RequiredArgsConstructor
@Api(tags = "后台用户管理")
@RequestMapping("/admin")
public class SysAdminController {

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    private final SysAdminService adminService;

    private final SysRoleService roleService;

    private final SysMenuService sysMenuService;

    private final SysCaptchaService sysCaptchaService;

    @ApiOperation(value = "登录验证码")
    @GetMapping(value = "/captcha")
    public ObjectResult<String> captcha(String uuid) {
        String image = sysCaptchaService.getCaptcha(uuid);
        return ObjectResult.success(image);
    }

    @ApiOperation(value = "用户注册")
    @PostMapping(value = "/register")
    public ObjectResult<SysAdmin> register(@Validated @RequestBody SysAdminParam sysAdminParam) {
        SysAdmin sysAdmin = adminService.register(sysAdminParam);
        if (sysAdmin == null) {
            return ObjectResult.failed();
        }
        return ObjectResult.success(sysAdmin);
    }

    @ApiOperation(value = "用户登录")
    @PostMapping(value = "/login")
    public ObjectResult<Object> login(@Validated @RequestBody SysAdminLoginParam form) {
        boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
        if (!captcha) {
            return ObjectResult.failed(ResultCode.VALIDATE_FAILED, "验证码不正确");
        }
        String token = adminService.login(form.getUsername(), form.getPassword());
        if (token == null) {
            return ObjectResult.validateFailed("用户名或密码错误");
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);
        return ObjectResult.success(tokenMap);
    }

    @ApiOperation(value = "刷新token")
    @GetMapping(value = "/refreshToken")
    public ObjectResult<Object> refreshToken(HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        String refreshToken = adminService.refreshToken(token);
        if (refreshToken == null) {
            return ObjectResult.failed("token已经过期！");
        }
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("token", refreshToken);
        tokenMap.put("tokenHead", tokenHead);
        return ObjectResult.success(tokenMap);
    }

    @ApiOperation(value = "用户信息")
    @GetMapping(value = "/info")
    public ObjectResult<Object> getAdminInfo(Principal principal) {
        if (principal == null) {
            return ObjectResult.unauthorized(null);
        }
        String username = principal.getName();
        SysAdmin sysAdmin = adminService.getAdminByUsername(username);
        Map<String, Object> data = new HashMap<>();
        data.put("username", sysAdmin.getUsername());
        data.put("icon", sysAdmin.getIcon());
        // 角色查询菜单
        List<SysMenuNode> menus = sysMenuService.listMenuTreeByUserId(sysAdmin.getId());
        // 构建路由菜单
        List<RouterVo> routerList = sysMenuService.buildMenus(menus);
        data.put("menus", routerList);
        // 角色查询
        List<SysRole> roleList = adminService.getRoleList(sysAdmin.getId());
        if (CollUtil.isNotEmpty(roleList)) {
            List<String> roles = roleList.stream().map(SysRole::getName).collect(Collectors.toList());
            data.put("roles", roles);
        }
        return ObjectResult.success(data);
    }

    @ApiOperation(value = "用户登出")
    @PostMapping(value = "/logout")
    public ObjectResult<Object> logout() {
        return ObjectResult.success();
    }

    @ApiOperation("用户分页列表")
    @GetMapping(value = "/list")
    public ObjectResult<PageResult<SysAdmin>> list(
            @RequestParam(value = "keyword", required = false) String keyword,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum) {
        Page<SysAdmin> adminList = adminService.list(keyword, pageSize, pageNum);
        return ObjectResult.success(PageResult.restPage(adminList));
    }

    @ApiOperation("获取用户信息")
    @GetMapping(value = "/{id}")
    public ObjectResult<SysAdmin> getItem(@PathVariable Long id) {
        SysAdmin admin = adminService.getById(id);
        return ObjectResult.success(admin);
    }

    @ApiOperation("修改用户信息")
    @PostMapping(value = "/update/{id}")
    public ObjectResult<Object> update(@PathVariable Long id, @RequestBody SysAdmin admin) {
        boolean success = adminService.update(id, admin);
        if (success) {
            return ObjectResult.success();
        }
        return ObjectResult.failed();
    }

    @ApiOperation("修改用户密码")
    @PostMapping(value = "/updatePassword")
    public ObjectResult<Object> updatePassword(@Validated @RequestBody UpdatePasswordParam updatePasswordParam) {
        int status = adminService.updatePassword(updatePasswordParam);
        if (status > 0) {
            return ObjectResult.success(status);
        } else if (status == -1) {
            return ObjectResult.failed("提交参数不合法");
        } else if (status == -2) {
            return ObjectResult.failed("找不到该用户");
        } else if (status == -3) {
            return ObjectResult.failed("旧密码错误");
        } else {
            return ObjectResult.failed();
        }
    }

    @ApiOperation("删除用户信息")
    @PostMapping(value = "/delete/{id}")
    public ObjectResult<Object> delete(@PathVariable Long id) {
        boolean success = adminService.delete(id);
        if (success) {
            return ObjectResult.success();
        }
        return ObjectResult.failed();
    }

    @ApiOperation("修改帐号状态")
    @PostMapping(value = "/updateStatus/{id}")
    public ObjectResult<Object> updateStatus(@PathVariable Long id, @RequestParam(value = "status") Integer status) {
        SysAdmin sysAdmin = new SysAdmin();
        sysAdmin.setStatus(status);
        boolean success = adminService.update(id, sysAdmin);
        if (success) {
            return ObjectResult.success();
        }
        return ObjectResult.failed();
    }

    @ApiOperation("用户分配角色")
    @PostMapping(value = "/role/update")
    public ObjectResult<Object> updateRole(@RequestParam("adminId") Long adminId,
                                   @RequestParam("roleIds") List<Long> roleIds) {
        int count = adminService.updateRole(adminId, roleIds);
        if (count >= 0) {
            return ObjectResult.success(count);
        }
        return ObjectResult.failed();
    }

    @ApiOperation("获取用户角色")
    @GetMapping(value = "/role/{adminId}")
    public ObjectResult<List<SysRole>> getRoleList(@PathVariable Long adminId) {
        List<SysRole> roleList = adminService.getRoleList(adminId);
        return ObjectResult.success(roleList);
    }

}
